class BluetoothManager {
    constructor() {
        if (!BluetoothManager.instance) {
            BluetoothManager.instance = this;
            this.bluetoothDevice = {
                deviceId: "60:E8:5B:6C:26:08",
                deviceName: "sitting",
                serviceId: "0000FFE0-0000-1000-8000-00805F9B34FB",
                // 0000FFF4-0000-1000-8000-00805F9B34FB
                // 0000FFF5-0000-1000-8000-00805F9B34FB
                characterId: "0000FFE1-0000-1000-8000-00805F9B34FB",
                connectionStatus: false
            };
            this.callback = null;
			this.timer = null;
			this.deviceId='60:E8:5B:6C:26:08';
			this.serviceId= '0000FFE0-0000-1000-8000-00805F9B34FB';
			this.characteristicId= '0000FFE1-0000-1000-8000-00805F9B34FB';
        }
        return BluetoothManager.instance;
    }

    // 设置外部传入的回调函数
    setCallback(callback) {
        this.callback = callback;
    }

    // 封装外部可调用的方法，例如连接设备
    connectToDevice() {
        // ...实现根据设备名查找并连接的逻辑...
        uni.showLoading({
            title: "连接中"
        })
        this.initBlue();
    }
		// 外部进行使用进行监听
    handleValue() {
        this.notify();
    }

    // 1.初始化蓝牙
    initBlue() {
        try {
            uni.openBluetoothAdapter({
                success: (res) => {
                    console.log("初始化蓝牙成功");
                    console.log(res);
                    this.startBluetoothDiscovery();
                },
                fail: (err) => {
                    console.error(err);
                    this.handleError("请开启蓝牙");
                },
            });
        } catch (err) {
            this.handleError("蓝牙初始化异常");
        }
    }
    // 2 开启蓝牙搜索
    startBluetoothDiscovery() {
        let retryCount = 0;
        console.log("蓝牙搜索中");
        const startDiscovery = () => {
            uni.startBluetoothDevicesDiscovery({
								allowDuplicatesKey: true,
                success: (res) => {
                    console.log("蓝牙搜索已启动", res);
                    this.listenBluetoothDevices();
                },
                fail: (err) => {
                    console.error("启动蓝牙搜索失败", err);
                    if (retryCount < 3) {
                        retryCount++;
                        setTimeout(startDiscovery, 1000 * retryCount); // 一秒后进行重试
                    } else {
                        this.handleError('蓝牙搜索失败,请检查设备是否开启')
                    }
                },
            });
        };
        startDiscovery();
        console.log("蓝牙搜索结束");
    }

    // 3.监听搜寻到新设备
    listenBluetoothDevices() {
				this.timer = setTimeout(() => {
            this.stopBluetoothDiscovery();
            this.handleError("连接超时，请检查蓝牙是否开启");
        }, 10000);
        uni.onBluetoothDeviceFound((res) => {
            this.handleConnection(res, this.bluetoothDevice);
        })
    }

    // 4. 对搜索到的设备进行判断,是否是我们要连接的设备
    handleConnection(res, deviceInfo) {
        const devices = res.devices;
        for (let i = 0; i < devices.length; i++) {
            console.log(
                "name:" +
                devices[i].name +
                " id: " +
                devices[i].deviceId +
                ", uuid: " +
                devices[i].advertisServiceUUIDs
            );
            if (devices[i].name == deviceInfo.deviceName) {
                this.handleBluetoothDeviceClick(devices[i]);
                break;
            }
        }
    }

    // 5 相当于选择了目标蓝牙进行连接
    handleBluetoothDeviceClick(device) {
        console.log(
            "连接目标蓝牙设备" + device.deviceId + " " + device.advertisServiceUUIDs
        );
        uni.createBLEConnection({
            deviceId: device.deviceId,
            success: (res) => {
                console.log("蓝牙设备连接成功", res);
                // 停止蓝牙搜索
                this.bluetoothDevice.connectionStatus = true;
                this.stopBluetoothDiscovery();
                uni.hideLoading();
                uni.showToast({
                    title: '蓝牙连接成功',
                    duration: 1500
                });
								clearTimeout(this.timer);
								this.timer = null;
            },
            fail: (err) => {
                console.log('蓝牙搜索失败', err);
                this.handleError('蓝牙搜索失败')
            },
        });
    }

    // 6 在完成了1到5之后,知道了特征值,直接进行消息监听
        notify() {
            uni.notifyBLECharacteristicValueChange({
                deviceId: this.deviceId,
                serviceId: this.serviceId,
                characteristicId: this.characteristicId,
				state:true,
                success: (res) => {
                    console.log(res);
                    this.listenValueChange();
                    uni.showToast({
                        title: '已开启监听'
                    });
                },
                fail(err) {
                    console.error(err);
                    uni.showToast({
                        title: '监听失败',
                        icon: 'error'
                    });
                }
            });
        }

    // 在调用notify后就可以开始被监听到了
    listenValueChange() {
        uni.onBLECharacteristicValueChange(res => {
            console.log(res)
            let resHex = this.ab2hex(res.value)
            console.log(resHex)
            let result = this.hexCharCodeToStr(resHex)
            console.log(String(result))
            if (typeof this.callback === 'function') {
                this.callback(
                    resHex,
					result
                ); // 调用外部回调
            }
        })
    }
	

    ab2hex(buffer) {
        const hexArr = Array.prototype.map.call(
            new Uint8Array(buffer),
            function (bit) {
                return (bit.toString(16)).slice(-2)
            }
        )
        return hexArr.join('')
    }
	
    hexCharCodeToStr(hexCharCodeStr) {
        var trimedStr = hexCharCodeStr.trim();
        var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
        var len = rawStr.length;
        if (len % 2 !== 0) {
            console.error(); ("存在非法字符!");
            return "";
        }
        var curCharCode;
        var resultStr = [];
        for (var i = 0; i < len; i = i + 2) {
            curCharCode = parseInt(rawStr.substr(i, 2), 16);
            resultStr.push(String.fromCharCode(curCharCode));
        }
        return resultStr.join("");
    }


    // 这个方法只有在调试的时候进行使用,判断有哪些特征值
    getCharacteristics() {
        console.log('获取特征值...')
        uni.getBLEDeviceCharacteristics({
            deviceId: this.bluetoothDevice.deviceId, // 设备ID
            serviceId: this.bluetoothDevice.serviceId, // 服务UUID
            success: (res) => {
                for (let i = 0; i < res.characteristics.length; i++) {
                    console.log(res.characteristics[i]);
                }
            },
            fail: (err) => {
                console.error("获取特征值失败", err);
                uni.hideLoading();
                uni.showModal({
                    title: "连接失败",
                    duration: 1500
                })
            },
        });
    }

    stopBluetoothDiscovery() {
        uni.stopBluetoothDevicesDiscovery({
            success: (res) => {
                console.log("蓝牙搜索已停止", res);
            },
            fail: (err) => {
                console.error("停止蓝牙搜索失败", err);
            },
        });
    }
    closeConnection() {
        console.log("正在断开连接");
        uni.closeBLEConnection({
            deviceId: this.deviceId,
            success: (res) => {
                console.log(res);
                console.log("断开连接成功");
                this.bluetoothDevice.connectionStatus = false;
            },
            fail: (err) => {
                console.log(err);
                console.log("断开连接失败");
            },
        });
    }

    handleError(message) {
        uni.hideLoading();
		if(!this.bluetoothDevice.connectionStatus) {
			uni.showToast({
			    title: message,
			    duration: 1500,
			});
		}
        console.error(message);
    }


}

export const BluetoothUtil = new BluetoothManager();
